package com.gitee.huanminabc.jcommon.reflect;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


public class ClassMatcher {

    /**
     * com.**.WorkEntity.sayHello(..)
     * com.**.WorkEntity.*(..)
     * com.**.test.*.sayHello(..)
     * com.*.test.*.*(..)
     * com.*.test.*.say*(..)
     * com.**.WorkEntity.sayHello(java.lang.String)
     * com.**.WorkEntity.say*(*,java.lang.Integer)
     */
    public static List<Method> match(List<Class<?>> classes, String rule) {
        String regexPattern = getRegexPattern(rule);

        // 使用 parallelStream 并发处理
        return classes.parallelStream()
                .flatMap(clazz -> Arrays.stream(clazz.getDeclaredMethods())
                        .filter(method -> {
                            String methodDescriptor = buildMethodDescriptor(clazz.getName(), method);
                            return Pattern.matches(regexPattern, methodDescriptor);
                        }))
                .collect(Collectors.toList());
    }

    private static String buildMethodDescriptor(String className, Method method) {
        StringBuilder sb = new StringBuilder(className);
        sb.append('.').append(method.getName()).append('(');
        Class<?>[] parameterTypes = method.getParameterTypes();
        for (int i = 0; i < parameterTypes.length; i++) {
            sb.append(parameterTypes[i].getName());
            if (i < parameterTypes.length - 1) {
                sb.append(',');
            }
        }
        sb.append(')');
        return sb.toString();
    }

    private static String getRegexPattern(String pattern) {
        // Replace wildcards in the pattern with regex equivalents
        String regexPattern = pattern
                .replace(".", "\\.")
                .replace("*", ".*")
                .replace("(", "\\(")
                .replace(")", "\\)")
                .replace("\\(\\.\\.\\)", "\\(.*\\)");

        // Ensure the pattern matches the whole string
        regexPattern = "^" + regexPattern + "$";
        return regexPattern;
    }


}